#pragma once

#include <iostream>
#include <vector>
#include <bitset>
using namespace std;

namespace rtx
{
	template<size_t N>
	class bitset
	{
	public:
		bitset()
		{
			//_bits.resize(N / 8 + 1, 0); 
			_bits.resize((N >> 3) + 1, 0); // 即上面注释的，效率快一点点
		}

		void set(size_t x)
		{
			size_t i = x >> 3; // 将x映射在位图中的位置计算出来。
			size_t j = x % 8; // //映射到char中第几个比特位

			_bits[i] |= (1 << j); //将映射的比特位置1。
		}

		void reset(size_t x)
		{
			size_t i = x >> 3; // 将x映射在位图中的位置计算出来。
			size_t j = x % 8; // //映射到char中第几个比特位

			_bits[i] &= ~(1 << j); //将映射的比特位置0，这里~是按位取反，不要用到!逻辑取反
		}

		bool test(size_t x)
		{
			size_t i = x >> 3; // 将x映射在位图中的位置计算出来。
			size_t j = x % 8; // //映射到char中第几个比特位

			return _bits[i] & (1 << j); //与上除了对应比特位是1，其它位都是0的数，得到对应比特位bool值
		}

	protected:
		vector<char> _bits;
	};

	template<size_t N>
	class two_bitset
	{
	public:
		void set(size_t x)
		{
			bool inset1 = _bs1.test(x); // 测试当前状态
			bool inset2 = _bs2.test(x);

			if (inset1 == false && inset2 == false)
			{
				_bs2.set(x); // 00 -> 01
			}
			else if (inset1 == false && inset2 == true)
			{
				_bs1.set(x); // 01 -> 10
				_bs2.reset(x);
			}     
			else if (inset1 == true && inset2 == false)
			{
				_bs1.set(x); // 10 -> 11
				_bs2.reset(x);
			}   // 11 是出现三次或三次以上，不用变
		}

		void print_once_num()
		{
			for (size_t i = 0; i < N; ++i)
			{
				if (_bs1.test(i) == false && _bs2.test(i) == true)
				{
					cout << i << endl; // 打印只出现一次的整数
				}
			}
		}

	protected:
		bitset<N> _bs1;
		bitset<N> _bs2;
		//std::bitset<N> _bs1;
		//std::bitset<N> _bs2;
	};
}